/*************************************************************************
*																		 *
*				code by Miles Chen (v-mich) 2007.9.18					 *
*																		 *
*																		 *
*************************************************************************/
#pragma once
#include "stdafx.h"

#define MAIL_ADDRESS L"mail.163.com"
#define SHORT_SLEEP_TIME 200
#define MAX_TRY_TIME 100

class CMailTool
{
public:
	CMailTool()
	{
	
	}
	~CMailTool()
	{
	
	}

protected:
	void OnMailWalkthrough(HWND hDlg)
	{
		WCHAR szUID[MAX_CHAR];
		WCHAR szPWD[MAX_CHAR];
		IWebBrowser2 *pwb = NULL;
		IHTMLDocument2 *pHTMLDoc = NULL;
		IDispatch *pdisp = NULL;
		VARIANT v = { VT_EMPTY };
		VARIANT_BOOL fBusy;
		int nTryTime;
		BSTR bstrReadyState = NULL;
		BSTR bstrURL = NULL;
		HRESULT hr;

		// Get UID and PWD
		GetDlgItemTextW(hDlg, IDC_MAIL_UID, szUID, MAX_CHAR);
		GetDlgItemTextW(hDlg, IDC_MAIL_PWD, szPWD, MAX_CHAR);

		if(wcslen(szUID)==0 || wcslen(szPWD)==0)
		{
			MessageBoxW(hDlg, L"You need a ID and password to login mail system.", L"Prompt", MB_OK | MB_ICONINFORMATION);
			return;
		}
		
		// CreateInstance
		hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (LPVOID*)&pwb);
		if(FAILED(hr))
		{
			MessageBoxW(hDlg, L"Cannot create IE instance.", L"Error", MB_OK | MB_ICONERROR);
			goto exit;
		}

		// Navigate
		bstrURL = SysAllocString(MAIL_ADDRESS);
		hr = pwb->Navigate(bstrURL, &v, &v, &v, &v);
		SysFreeString(bstrURL);
		if(FAILED(hr))
		{
			MessageBoxW(hDlg, L"Cannot navigate to mail address.", L"Error", MB_OK | MB_ICONERROR);
			goto exit;
		}

		// Show
		hr = pwb->put_Visible(VARIANT_TRUE);
		if(FAILED(hr))
		{
			MessageBoxW(hDlg, L"Cannot set IE to visible.", L"Error", MB_OK | MB_ICONERROR);
			goto exit;
		}

		// WaitBrowser
		nTryTime = 0;
		while(TRUE)
		{
			hr = pwb->get_Busy(&fBusy);
			if(FAILED(hr))
			{
				MessageBoxW(hDlg, L"Cannot get browser BUSY property.", L"Error", MB_OK | MB_ICONERROR);
				goto exit;
			}
			if(fBusy)
			{
				Sleep(SHORT_SLEEP_TIME);
				if(nTryTime++ > MAX_TRY_TIME)
				{
					MessageBoxW(hDlg, L"Timeout when wait for browser ready.", L"Error", MB_OK | MB_ICONERROR);
					goto exit;
				}
			}
			else
				break;
		}

		// Get DomDocument
		hr = pwb->get_Document(&pdisp);
		if(FAILED(hr))
		{
			MessageBoxW(hDlg, L"Cannot QueryInterface for IDispatch.", L"Error", MB_OK | MB_ICONERROR);
			goto exit;
		}
		hr = pdisp->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&pHTMLDoc);
		if(FAILED(hr))
		{
			MessageBoxW(hDlg, L"Cannot QueryInterface for IHTMLDocument2.", L"Error", MB_OK | MB_ICONERROR);
			goto exit;
		}

		// WaitDocument
		nTryTime = 0;
		while(TRUE)
		{
			hr = pHTMLDoc->get_readyState(&bstrReadyState);
			if(FAILED(hr))
			{
				MessageBoxW(hDlg, L"Cannot get DomDocument READYSTATUS property.", L"Error", MB_OK | MB_ICONERROR);
				goto exit;
			}
			if(wcscmp(bstrReadyState, L"complete") != 0 && wcscmp(bstrReadyState, L"interactive") != 0)
			{
				Sleep(SHORT_SLEEP_TIME);
				if(nTryTime++ > MAX_TRY_TIME)
				{
					MessageBoxW(hDlg, L"Timeout when wait for document ready.", L"Error", MB_OK | MB_ICONERROR);
					goto exit;
				}
			}
			else
				break;
			SysFreeString(bstrReadyState);
		}

		// UI Automation
		SetInputText(pHTMLDoc, L"username", szUID);
		SetInputText(pHTMLDoc, L"password", szPWD);
		ClickButton(pHTMLDoc, L"btn2");


exit:
		if(pwb) pwb->Release();
		if(pHTMLDoc) pHTMLDoc->Release();
		if(pdisp) pdisp->Release();
		if(bstrReadyState) SysFreeString(bstrReadyState);
	}

	HRESULT SetInputText(IHTMLDocument2 *pHTMLDoc, BSTR lpszElementName, BSTR lpszValue)
	{
		HRESULT hr;
		IHTMLDocument3 *pHTMLDoc3 = NULL;
		IHTMLElementCollection *pelColl = NULL;
		IDispatch* pdisp = NULL;
		IHTMLInputElement *p = NULL;
		IHTMLTxtRange *ptr = NULL;
		VARIANT vIndex = { VT_I4 };
		BSTR bstrBuffer = NULL;

		hr = pHTMLDoc->QueryInterface(IID_IHTMLDocument3, (LPVOID*)&pHTMLDoc3);
		if(FAILED(hr))
			goto exit;

		bstrBuffer = SysAllocString(lpszElementName);
		hr = pHTMLDoc3->getElementsByName(bstrBuffer, &pelColl);
		SysFreeString(bstrBuffer);
		if(FAILED(hr))
			goto exit;

		vIndex.intVal = 0;
		hr = pelColl->item(vIndex, vIndex, &pdisp);
		if(FAILED(hr))
			goto exit;

		hr = pdisp->QueryInterface(IID_IHTMLInputElement, (LPVOID*)&p);
		if(FAILED(hr))
			goto exit;

		hr = p->createTextRange(&ptr);
		if(FAILED(hr))
			goto exit;

		bstrBuffer = SysAllocString(lpszValue);
		hr = ptr->put_text(bstrBuffer);
		SysFreeString(bstrBuffer);
		if(FAILED(hr))
			goto exit;

exit:
		if(p) p->Release();
		if(pelColl) pelColl->Release();
		if(pdisp) pdisp->Release();
		if(ptr) ptr->Release();
		if(pHTMLDoc3) pHTMLDoc3->Release();
		return hr;
	}

	HRESULT ClickButton(IHTMLDocument2 *pHTMLDoc, BSTR lpszElementID)
	{
		HRESULT hr;
		IHTMLDocument3 *pHTMLDoc3 = NULL;
		IHTMLElement *p = NULL;
		BSTR bstrBuffer = NULL;

		hr = pHTMLDoc->QueryInterface(IID_IHTMLDocument3, (LPVOID*)&pHTMLDoc3);
		if(FAILED(hr))
			goto exit;

		bstrBuffer = SysAllocString(lpszElementID);
		hr = pHTMLDoc3->getElementById(bstrBuffer, &p);
		SysFreeString(bstrBuffer);
		if(FAILED(hr))
			goto exit;

		hr = p->click();
		if(FAILED(hr))
			goto exit;


exit:
		if(p) p->Release();
		if(pHTMLDoc3) pHTMLDoc3->Release();
		return hr;
	}
};